package cn.imvc.app.models;

import java.util.Date;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

import cn.imvc.app.domains.FundFlowType;
import cn.imvc.app.domains.OrderState;
import cn.imvc.app.entities.Commission;
import cn.imvc.app.entities.Dealer;
import cn.imvc.app.entities.DealerLevel;
import cn.imvc.app.entities.FundFlow;
import cn.imvc.app.entities.Member;
import cn.imvc.app.repositories.DealerRepository;
import cn.imvc.data.domain.ViewRequest;
import cn.imvc.data.util.JpqlUtil;
import cn.imvc.data.util.PageableUtil;

@Service("dealerModel")
public class DealerModelImpl implements DealerModel {
	private static final Logger log = Logger.getLogger(DealerModelImpl.class);
	@Autowired
	private DealerRepository dealerRepository;
	@Autowired
	private DealerLevelModel dealerLevelModel;
	@Autowired
	private AccountModel accountModel;
	@Autowired
	private FundFlowModel fundFlowModel;
	@Autowired
	private CommissionModel commissionModel;
	@Autowired
	private MemberModel memberModel;

	public Page<Object []> findAll(int id,ViewRequest viewRequest) {
		if(viewRequest == null){
			viewRequest = new ViewRequest();
		}
		if(id != 0){
			viewRequest.getParams().put("_and_m_dot_parentId_eq_number",""+id);
		}
//		String sql = null;
//		if(id != 0){
//		sql = "select d.id AS id,d.memberId AS memberId,d.name AS name,d.dealerLevelId AS dealerLevelId,d.wxqrcode AS wxqrcode,d.appqrcode AS appqrcode,d.domain AS domain,d.createdAt AS createdAt,d.updatedAt AS updatedAt,membertmp.parentId as parentId,membertmp.parentName as parentName,membertmp.secondSubSum AS secondSubSum,membertmp.thirdSubSum AS thirdSubSum from (((select a.id AS idtmp,a.parentId AS parentId,b.name AS parentName,sum((case when (b.guid regexp concat('^',a.guid,',[0-9]*$')) then 1 else 0 end)) AS secondSubSum,sum((case when (b.guid regexp concat('^',a.guid,',[0-9]*,[0-9]*$')) then 1 else 0 end)) AS thirdSubSum from (member a join member b) "
//					+ "on a.parentId = " + id
//					+ " group by a.id)) membertmp join ishop.dealer d) where (membertmp.idtmp = d.memberId)";
//		}else{
//		sql = "select d.id AS id,d.memberId AS memberId,d.name AS name,d.dealerLevelId AS dealerLevelId,d.wxqrcode AS wxqrcode,d.appqrcode AS appqrcode,d.domain AS domain,d.createdAt AS createdAt,d.updatedAt AS updatedAt,membertmp.parentId as parentId,membertmp.parentName as parentName,membertmp.secondSubSum AS secondSubSum,membertmp.thirdSubSum AS thirdSubSum from (((select a.id AS idtmp,a.parentId AS parentId,b.name AS parentName,sum((case when (b.guid regexp concat('^',a.guid,',[0-9]*$')) then 1 else 0 end)) AS secondSubSum,sum((case when (b.guid regexp concat('^',a.guid,',[0-9]*,[0-9]*$')) then 1 else 0 end)) AS thirdSubSum from (member a join member b) group by a.id)) membertmp join ishop.dealer d) where (membertmp.idtmp = d.memberId)";
//		}
		String sql = "SELECT d.id, d.memberId,d.`name`,dl.level,d.wxqrcode,d.appqrcode,d.domain,d.createdAt,d.updatedAt,"
				+"(SELECT COUNT(m2.id) FROM member m2 WHERE m2.guid regexp concat('^',m.guid,',[0-9]*$')) secondSubSum,"
				+"(SELECT COUNT(m3.id) FROM member m3 WHERE m3.guid regexp concat('^',m.guid,',[0-9]*,[0-9]*$')) thirdSubSum,m.parentId,pm.name as pname,m.name as mname" 
				+" FROM member m INNER JOIN dealer d ON m.id=d.memberId left join member pm on m.parentId = pm.id left join dealer_level dl on dl.id = d.dealerLevelId "
				+ JpqlUtil.toWhere(viewRequest.getParams())
				+ " ORDER BY d.id DESC";
		return dealerRepository.findAllSql(sql, PageableUtil.toPageable(viewRequest));
	}

	public Dealer getOne(int id) {
		return dealerRepository.getOne(id);
	}

	@Override
	public void updateLevel(int id,Dealer dealer) {
		Dealer oldDealer = dealerRepository.getOne(id);
		oldDealer.setDealerLevel(dealerLevelModel.getOne(dealer.getDealerLevel().getId()));
		dealerRepository.saveAndFlush(oldDealer);
	}

	@Override
	public List<Dealer> findByDealerLevel(DealerLevel dealerLevel) {
		return dealerRepository.findByDealerLevel(dealerLevel);
	}

	/*@Override
	public void updatePointAuto(Dealer dealer) {
		dealer.setDealerLevel(dealerLevelModel.findByLevel((dealer.getDealerLevel().getLevel()+1)).get(0));
		dealerRepository.saveAndFlush(dealer);
		accountModel.retrySaveAccount(dealer.getMember().getAccount().getId(), 0, 0, -1000);
	}*/
	
	@Override
	public void updatePointAuto(Dealer dealer) {
/*		String sql = "select SUM(resultAmount - refundAmount - freightAmount) as sum from orders where state >= '60' and memberId = "+dealer.getMember().getId();
		List<Object[]> objList = dealerRepository.findAllSql(sql);
		Object obj = objList.get(0);
		Integer  theTotalMoney = Integer.parseInt(obj == null?"0":obj.toString());
		if(theTotalMoney >= 100000){
			dealer.setDealerLevel(dealerLevelModel.findByLevel(2).get(0));
			dealerRepository.saveAndFlush(dealer);
			log.info("分销商id:::"+dealer.getId()+"升级为经销商。");
		}
*/	
		String sql = "select count(*) from orders where state >= '60' and memberId = "+dealer.getMember().getId();
		List<Object[]> objList = dealerRepository.findAllSql(sql);
		Object obj = objList.get(0);
		Integer  theTotalMoney = Integer.parseInt(obj == null?"0":obj.toString());
		if(theTotalMoney >= 10){
			dealer.setDealerLevel(dealerLevelModel.findByLevel(2).get(0));
			dealerRepository.saveAndFlush(dealer);
			log.info("分销商id:::"+dealer.getId()+"升级为经销商。");
		}
	
	}

	@Override
	public List<Dealer> findByDealerLevelNot(DealerLevel dealerLevel) {
		return dealerRepository.findByDealerLevelNot(dealerLevel);
	}
	
		
	@Override
	public void updateTeamCommission(Dealer dealer, String theDate) {
		Double thePercent = dealer.getDealerLevel().getPercent();
		/*if (dealer.getDealerLevel().getType() == 2) {*/
			// 代理分佣开始
			String sql1 = "select group_concat(id) from member where guid like '" + dealer.getMember().getId() + ",%'";
			Object obj1 = dealerRepository.findAllSql(sql1).get(0);
			String idString = obj1 == null ? "''" : obj1.toString();
			
			String agentCommissisonSqlBegin = "UPDATE orders o SET o.agentCommission = 1 where o.state >= '60' and DATE_FORMAT(o.finishTime,"+"'%Y-%m') = '" + theDate
					+ "' and o.memberId in ("+idString+") and (o.agentCommission = 0 or o.agentCommission IS NULL)";
			dealerRepository.updateSql(agentCommissisonSqlBegin);
			try {

				String sql = "select SUM(resultAmount - refundAmount - freightAmount) as sum from orders where state >= '60' and DATE_FORMAT(finishTime,"+"'%Y-%m') = '" + theDate
						+ "' and memberId in ("+idString+") and agentCommission = 1";
				List<Object[]> objList = dealerRepository.findAllSql(sql);
				Object obj = objList.get(0);
				Integer theTotalMoney = Integer.parseInt(obj == null ? "0" : obj.toString());
				if (theTotalMoney != 0) {
					int teamCommissionMoney = (int) (theTotalMoney * thePercent / 100);
					fundFlowModel.saveFundFlow(dealer.getMember(), teamCommissionMoney, "", FundFlowType.TeamAward.getValue());
					accountModel.retrySaveAccount(dealer.getMember().getAccount().getId(), teamCommissionMoney, teamCommissionMoney, 0);
					// 分佣表插入
					Commission commOne = new Commission();
					commOne.setMember(dealer.getMember());
					commOne.setAccount(dealer.getMember().getAccount());
					commOne.setType((byte) 3);
					commOne.setReferId(0);
					commOne.setReferCode("");
					commOne.setMoney(teamCommissionMoney);
					commOne.setRate((int) ((dealer.getDealerLevel().getPercent()) * 1));
					commOne.setCreatedAt(new Date());
					commOne.setFromMember(null);
					commissionModel.save(commOne);

					// 代理分佣结束
					String agentCommissisonSqlEnd = "UPDATE orders SET agentCommission = 2 where state >= '60' and DATE_FORMAT(finishTime,"+"'%Y-%m') = '" + theDate
							+ "' and memberId in ("+idString+") and agentCommission = 1";
					dealerRepository.updateSql(agentCommissisonSqlEnd);
				}
			} catch (Exception e) {
				// 代理分佣失败
				String agentCommissisonSqlFail = "UPDATE orders SET agentCommission = 3 where state >= '60' and DATE_FORMAT(finishTime,"+"'%Y-%m') = '" + theDate
						+ "' and memberId in ("+idString+") and agentCommission = 1";
				dealerRepository.updateSql(agentCommissisonSqlFail);
			}
		/*} else if (dealer.getDealerLevel().getLevel() == 2) {
			Integer sumMoney = 0;
			Member theMember = dealerRepository.getOne(dealer.getId()).getMember();
			String ids = "";
			if (!theMember.getMember().isEmpty()) {
				ids = getIsTeamMemberId(theMember, ids);
			}
			if (!ids.equals("")) {
				// 分销商分佣开始
				String dealerCommissisonSqlBegin = "UPDATE orders SET dealerCommission = 1 where state >= '60' and DATE_FORMAT(finishTime," + "'%Y-%m') = '" + theDate + "' and memberId in ("
						+ ids.substring(0, ids.length() - 1) + ") and (dealerCommission = 0 or dealerCommission IS NULL)";
				dealerRepository.updateSql(dealerCommissisonSqlBegin);
				try {
					String sql = "select SUM(resultAmount - refundAmount - freightAmount) as sum from orders where state >= '60' and DATE_FORMAT(finishTime," + "'%Y-%m') = '" + theDate
							+ "' and memberId in (" + ids.substring(0, ids.length() - 1) + ") and dealerCommission = 1";
					List<Object[]> objList = dealerRepository.findAllSql(sql);
					Object obj = objList.get(0);
					Integer theTotalMoney = Integer.parseInt(obj == null ? "0" : obj.toString());
					sumMoney += theTotalMoney;
					if (sumMoney != 0) {
						int teamCommissionMoney = (int) (sumMoney * thePercent / 100);
						fundFlowModel.saveFundFlow(dealer.getMember(), teamCommissionMoney, "", FundFlowType.TeamAward.getValue());
						accountModel.retrySaveAccount(dealer.getMember().getAccount().getId(), teamCommissionMoney, teamCommissionMoney, 0);
						// 分佣表插入
						Commission commOne = new Commission();
						commOne.setMember(dealer.getMember());
						commOne.setAccount(dealer.getMember().getAccount());
						commOne.setType((byte) 3);
						commOne.setReferId(0);
						commOne.setReferCode("");
						commOne.setMoney(teamCommissionMoney);
						commOne.setRate((int) ((dealer.getDealerLevel().getPercent()) * 1));
						commOne.setCreatedAt(new Date());
						commOne.setFromMember(null);
						commissionModel.save(commOne);
					}
					// 分销商分佣结束
					String dealerCommissisonSqlEnd = "UPDATE orders SET dealerCommission = 2 where state >= '60' and DATE_FORMAT(finishTime," + "'%Y-%m') = '" + theDate + "' and memberId in ("
							+ ids.substring(0, ids.length() - 1) + ") and dealerCommission = 1";
					dealerRepository.updateSql(dealerCommissisonSqlEnd);
				} catch (NumberFormatException e) {
					// 分销商分佣失败
					String dealerCommissisonSqlFail = "UPDATE orders SET dealerCommission = 3 where state >= '60' and DATE_FORMAT(finishTime," + "'%Y-%m') = '" + theDate + "' and memberId in ("
							+ ids.substring(0, ids.length() - 1) + ") and dealerCommission = 1";
					dealerRepository.updateSql(dealerCommissisonSqlFail);
				}
			}
		}*/
	}
	
	/**
	 * 分销商团队分佣的时候   判断分销商下面是不是有分销商团队
	 * @param superMemberId  当前分销商的id
	 * @param member 当前遍历的下级人员
	 * @return
	 */
	public String getIsTeamMemberId(Member member, String ids) {
		@SuppressWarnings("unchecked")
		Set<Member> members = memberModel.getOne(member.getId()).getMember();
		for (Member m : members) {
			ids += m.getId() + ",";
			if (m.getDealer().getDealerLevel().getLevel() == 1 && !m.getMember().isEmpty()) {
					ids = getIsTeamMemberId(m, ids);
			}
		}
		return ids;
	}

	@Override
	public List<Dealer> findByDealerLevelOrDealerLevel(DealerLevel dealerLevel, DealerLevel dealerLevel2) {
		return dealerRepository.findByDealerLevelOrDealerLevel(dealerLevel,dealerLevel2);
	}
}
